package tests;

import models.WordStore;

import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

public class JUnit_WordStore {
	
	WordStore wordStoreDefault;
	WordStore wordStoreSimple;
	
	@Before
	public void setUp() throws Exception {
		
		String [] fourWords = {"aaa","bbb","aaa","ccc"};
		wordStoreDefault = new WordStore();
		wordStoreSimple = new WordStore(fourWords);

	}
	
	@After
	public void tearDown() throws Exception {
		
		wordStoreDefault = null;
		wordStoreSimple = null;
	}

	/**
	 * tests the default constructor {@link WordStore#WordStore()}
	 */
	@Test
	public void testDefaultConstructor() {
			Assert.assertTrue(wordStoreDefault.invariant());
  	}
	
	/**
	 * tests the non-default constructor {@link WordStore#WordStore()}
	 */
	@Test
	public void testNonDefaultConstructor() {
			Assert.assertTrue(wordStoreSimple.invariant());
  	}
	
	
	/**
	 * tests the addWord method {@link WordStore#addWord(String str)}
	 */
	@Test
	public void testAddWord() {
		    wordStoreDefault.addWord("aaa");
			Assert.assertEquals(wordStoreDefault.numberOfWords(), 1);
			Assert.assertTrue(wordStoreDefault.hasWord("aaa"));
			wordStoreDefault.addWord("aaa");
			Assert.assertEquals(wordStoreDefault.numberOfWords(), 1);
			Assert.assertTrue(wordStoreDefault.hasWord("aaa"));
			wordStoreDefault.addWord("bbbb");
			Assert.assertEquals(wordStoreDefault.numberOfWords(), 2);
			Assert.assertTrue(wordStoreDefault.hasWord("aaa"));
			Assert.assertTrue(wordStoreDefault.hasWord("bbbb"));
			Assert.assertFalse(wordStoreDefault.hasWord("cc"));
			wordStoreDefault.addWord("eeee");
			Assert.assertEquals(wordStoreDefault.numberOfWords(), 3);
			Assert.assertTrue(wordStoreDefault.hasWord("aaa"));
			Assert.assertTrue(wordStoreDefault.hasWord("bbbb"));
			Assert.assertTrue(wordStoreDefault.hasWord("eeee"));
			Assert.assertFalse(wordStoreDefault.hasWord("cc"));
				
			wordStoreSimple.addWord("ddd");
			Assert.assertEquals(wordStoreSimple.numberOfWords(), 4);
			Assert.assertTrue(wordStoreSimple.hasWord("aaa"));
			Assert.assertTrue(wordStoreSimple.hasWord("bbb"));
			Assert.assertTrue(wordStoreSimple.hasWord("ccc"));
			Assert.assertTrue(wordStoreSimple.hasWord("ddd"));
			Assert.assertFalse(wordStoreSimple.hasWord("eee"));
  	}
	
	/**
	 * tests the numberOfWords method {@link WordStore#numberOfWords()}
	 */
	@Test
	public void testNumberOfWords() {
		
		Assert.assertEquals(wordStoreSimple.numberOfWords(), 3);	
		Assert.assertEquals(wordStoreDefault.numberOfWords(), 0);
		
	}
	
	/**
	 * tests the exception for getting random word from an empty word store
	 */
	@Test(expected = IllegalStateException.class)
	public void testRandomElement_Exception() {
		
		wordStoreDefault.randomWord();
	}
	
	/**
	 * tests getting random word from a non-empty word store
	 */
	@Test
	public void testRandomElement() {
		
		String randomWord =null;
		for (int count =0; count<10; count++){
			randomWord = wordStoreSimple.randomWord();

		Assert.assertTrue(wordStoreSimple.hasWord(randomWord));
		Assert.assertTrue(randomWord == "aaa" || randomWord == "bbb" || randomWord == "ccc"	);
		}
	}
	
	 @Test
	 public void testToString() {
		 
			Assert.assertEquals(wordStoreDefault.toString(), "[]");
			Assert.assertEquals(wordStoreSimple.toString(), "[aaa, bbb, ccc]");
			
	 }
}
